经过前面的学习,我们已经把渲染引擎和低级可视化模块开发完了,也了解了对应的可视化概念。那么这一章我们就把已经开发好的这些模块串起来,完成“从0到1开发一个图表库”的这一任务。

这一章我们将从 Sparrow 的 API 介绍开始,然后梳理渲染流程,这之后再开始介绍关键代码。这一章可以说是整个实战环节的画龙点睛之笔,那么接下来就让我们开始吧!
# API 设计
首先我们来看看 API 设计,也就是了解一下该如何使用我们最后完成 Sparrow。
Sparrow 最终只暴露出一个函数:plot。该函数根据指定的 options 渲染图表并且返回一个渲染好的 SVG 元素。函数签名可以用 TypeScript 简单地如下定义:
plot(options: SPSpec): SVGSVGElement
@前端进阶之旅: 代码已经复制到剪贴板
至于这个 options 的结构用 TypeScript 可以简单地如下定义:
type SPSpec = SPNode;
type SPNode = {
type?: string;
data?: any[],
scales?: Recode<ChannelTypes, Scale>,
transforms?: Transform[],
statistics?: Statistic[],
encodings?: Recode<ChannelTypes, Encode>,
guides?: Recode<ChannelTypes, Guide>,
styles?: Record<string, string>
children?: SPNode[];
paddingLeft?: number,
paddingRight?: number,
paddingTop?: number,
paddingBottom?: number,
}
@前端进阶之旅: 代码已经复制到剪贴板
可以发现:它是一个嵌套的结构,描述的是上一章提到的视图树。
每一个节点的 type 除了上一章提到的 layer、col、row 这些容器节点之外,还可以是所有几何元素的类型:interval、area、text 等等,这些被称为视图节点,当然上一章提到的 facet 节点也算是一个视图节点。容器节点可以有 children 属性,但是视图节点不能有 children 属性。
下面对上面的节点的一些属性进行解释:
- data:任意类型的数据。
- scales:比例尺的配置,比如:
{type: 'ordinal', range: ['red', 'yellow']} - transforms:数据预处理配置,比如:
data => data.sort() - statistics:统计函数配置,比如:
{type: 'stackY'} - encodings:指定几何元素的每个通道用什么编码,比如:
{x: 'genre', y: 'sold'} - guides:指定辅助组件的配置,比如:
{type: 'axisY', display: false} - styles:指定几何元素的样式,比如:
{strokeWidth: 10} - paddingLeft:几何图形区域到整个图表区域的左边距。
- paddingRight:几何图形区域到整个图表区域的右边距。
- paddingTop:几何图形区域到整个图表区域的上边距。
- paddingBottom:几何图形区域到整个图表区域的下边距。
对于容器节点来说,上面的属性对其没有效果,但是会被后代中视图节点继承。比如下面两种写法其实是等价的。
// 可以理解为是下面的语法糖
const options = {
